package router

import (
	"encoding/json"
	"fmt"
	"goGin/tools"
	"net/http"
	"os"
	"time"

	"github.com/garyburd/redigo/redis"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"gorm.io/gorm"
)

type msgJson struct {
	Msg      string
	State    int
	Cid      int
	Fid      int
	Type     string
	Topimg   string
	Content  string
	Time     string
	Other    string
	Phone    int
	Username string
	Name     string
	Datatype string
}

var wsMap = make(map[string]*websocket.Conn)
var red redis.Conn
var Host string

// type wslst struct{}

var upGrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool { //设置跨域
		return true
	},
}

var nowmsg string

func setData(id string, c *gin.Context) {
	ws := wsMap[id]
	go readoffline(id)
	// defer ws.Close()
	ws.SetCloseHandler(func(code int, text string) error {
		fmt.Println(code, text, "连接已断开")
		ws.Close()        //关闭连接
		delete(wsMap, id) //删除缓存ws
		return nil
	})
	//读取ws中的数据
	go func() {
		for {
			t, c, err := ws.ReadMessage()
			// nowmsg = string(c)
			nowmsg := []byte(string(c))
			// fmt.Println(t, string(c))
			if err != nil {
				break
			}
			if t == -1 {
				return
			}
			obj := &msgJson{}
			errs := json.Unmarshal(nowmsg, obj)
			if errs != nil {
				fmt.Println("error:", errs)
				return
			}

			go sheinfo(id, obj)

			// msgbyte, err := json.Marshal(msg)
			// fmt.Println(msgbyte)
			//写入ws数据
			// err = ws.WriteMessage(1, msgbyte)
			// if err != nil {
			// 	return
			// }
		}
	}()
}
func readoffline(id string) { //读取离线信息
	ws := wsMap[id]
	fmt.Print(123)
	is_key_exit, err := redis.Bool(red.Do("EXISTS", "offline"+id))
	if err != nil {
		fmt.Print(err.Error())
		return
	}
	if is_key_exit == true {
		rs, errs := redis.String(red.Do("Get", "offline"+id))
		if errs != nil {
			fmt.Print(errs.Error())
			return
		}
		arrs := []*msgJson{}
		errss := json.Unmarshal([]byte(string(rs)), &arrs)
		if errss != nil {
			fmt.Print(err.Error())
			return
		}
		msgbyte, _ := json.Marshal(arrs)
		ws.WriteMessage(1, msgbyte)
		red.Do("DEL", "offline"+id)
		return
	}
}

func sheinfo(id string, obj *msgJson) { //设置消息
	// ws := wsMap[id]
	fidstr, _ := tools.Forstring(obj.Fid)
	msgbyte, _ := json.Marshal(obj)
	typenow := time.Now().String()
	if obj.Datatype == "addcontact" {

	} else if obj.Datatype == "setcontact" {

	} else if obj.Datatype == "radius" {
		var strobj tools.Savebase64fileType
		dir, _ := os.Getwd()
		strobj.Data = obj.Content
		strobj.Name = dir + "/../static/weixin/" + typenow + ".mp3"
		tools.Savebase64file(strobj)
		obj.Content = Host + "/static/weixin/" + typenow + ".mp3"
		timer := time.NewTimer(3 * 24 * time.Hour)
		<-timer.C
		//三天后删除文件
		tools.Delfile(strobj.Name)
	} else if obj.Datatype == "video" {
		var strobj tools.Savebase64fileType
		dir, _ := os.Getwd()
		strobj.Data = obj.Content
		strobj.Name = dir + "/../static/weixin/" + typenow + ".mp4"
		tools.Savebase64file(strobj)
		obj.Content = Host + "/static/weixin/" + typenow + ".mp4"
		timer := time.NewTimer(3 * 24 * time.Hour)
		<-timer.C
		//三天后删除文件
		tools.Delfile(strobj.Name)
	} else if obj.Datatype == "image" {
		var strobj tools.Savebase64imgType
		dir, _ := os.Getwd()
		strobj.Data = obj.Content
		strobj.Dir = dir + "/../static/weixin/" + typenow
		savedir, smalldir, imgtype := tools.Savebase64img(strobj)
		obj.Content = Host + "/static/weixin/" + typenow + imgtype
		timer := time.NewTimer(3 * 24 * time.Hour)
		<-timer.C
		//三天后删除文件
		tools.Delfile(savedir)
		tools.Delfile(smalldir)

	}
	if wsMap[fidstr] == nil {
		offline(obj)
		return
	}
	err := wsMap[fidstr].WriteMessage(1, msgbyte)
	// fmt.Print(id, obj, ws)

	// wsMap[fidstr].WriteMessage(1, msgbyte)
	// err := ws.WriteMessage(1, msgbyte)
	if err != nil {
		fmt.Print("ws写入错误")
		return
	}
}
func offline(obj *msgJson) { //处理离线消息
	key, _ := tools.Forstring(obj.Fid)
	is_key_exit, err := redis.Bool(red.Do("EXISTS", "offline"+key))
	if err != nil {
		fmt.Print(err.Error())
		return
	}
	arrs := []*msgJson{}
	if is_key_exit == true {
		rs, errs := redis.String(red.Do("Get", "offline"+key))
		if errs != nil {
			fmt.Print(errs.Error())
			return
		}
		errss := json.Unmarshal([]byte(string(rs)), &arrs)
		if errss != nil {
			fmt.Print(err.Error())
			return
		}
		arrs = append(arrs, obj)
		msgbyte, _ := json.Marshal(arrs)
		_, err := red.Do("Set", "offline"+key, msgbyte)
		// ws.WriteMessage(1, msgbyte)
		if err != nil {
			fmt.Print(err.Error())
		}
		return
	} else if is_key_exit == false {
		arrs = append(arrs, obj)
		msgbytes, _ := json.Marshal(arrs)
		_, err := red.Do("Set", "offline"+key, msgbytes)
		// rs, err := redis.String(red.Do("Get", "offline"+key))
		if err != nil {
			fmt.Print(err.Error())
			return
		}
	}
}
func Ws(r *gin.Engine, dbway *gorm.DB, d redis.Conn) {
	red = d
	r.GET("/ws/:id/:token", func(c *gin.Context) {
		Host = c.Request.Host
		//升级get请求为webSocket协议
		// rs, err := redis.String(red.Do("Get", "abc"))
		// str, _ := tools.Forstring(rs)
		// fmt.Print(rs, err)
		ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
		cid := c.Param("id")
		tokenString := c.Param("token")
		// types := c.Param("type")
		token, _, errs := tools.ParseToken(tokenString)
		// fmt.Print(token)
		// msg := msgJson{Msg: str, State: 400}
		// msgbyte, _ := json.Marshal(msg)
		// // fmt.Println(msgbyte)
		// //写入ws数据
		// _ = ws.WriteMessage(1, msgbyte)
		// return
		if errs != nil || !token.Valid {
			// ctx.JSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": "权限不足"})
			// ctx.Abort()
			msg := msgJson{Msg: "token错误！", State: 400}
			msgbyte, _ := json.Marshal(msg)
			// fmt.Println(msgbyte)
			//写入ws数据
			_ = ws.WriteMessage(1, msgbyte)
			return
		}
		if err != nil {
			return
		}
		wsMap[cid] = ws
		go setData(cid, c)
	})
}
